package com.qunar.train.mock.config;


import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import mockit.Mock;
import mockit.MockUp;
import qunar.tc.qswitch.client.QSwitch;
import qunar.tc.qswitch.client.QSwitchs;

public class MockQswitch<T> {

    private static ConcurrentMap<String, Object> qswitchMap = new ConcurrentHashMap<>();

    //适用于被Spring管理的单例模式，和静态属性
    public static void setProperty(Class clazz, String fieldName, Object newValue) {
        ResetFieldUtil.resetField(clazz, fieldName, newValue);
    }

    //直接对对象的属性赋值
    public static void setProperty(Object o, String fieldName, Object newValue) {
        ResetFieldUtil.resetField(o, fieldName, newValue);
    }

    public static void setBooleanProperty(Class clazz, String fieldName, final Boolean value) {
        ResetFieldUtil.resetField(clazz, fieldName, setQSwitchValue(value));
    }

    public static void setBooleanProperty(Object o, String fieldName, final Boolean value) {
        ResetFieldUtil.resetField(o, fieldName, setQSwitchValue(value));
    }

    public static void setStringProperty(Class clazz, String fieldName, final String value) {
        ResetFieldUtil.resetField(clazz, fieldName, setQSwitchValue(value));
    }

    public static void setStringProperty(Object o, String fieldName, final String value) {
        ResetFieldUtil.resetField(o, fieldName, setQSwitchValue(value));
    }

    public static QSwitch<Object> setQSwitchValue(final Object value) {
        QSwitch<Object> a = new QSwitch<Object>() {
            @Override
            public Object get() {
                return value;
            }

            @Override
            public Object get(Object t) {
                return null;
            }
        };
        return a;
    }

    public static void qswitchsMock() {

        new MockUp<QSwitchs>() {
            @Mock
            public void $clinit() {
            }

            @Mock
            public boolean isOn(String key, boolean defaultValue) {
                return (boolean) getValue(key, defaultValue, Boolean.class);
            }

            @Mock
            public int getInt(String key) {
                return getInt(key, -1);
            }

            @Mock
            public int getInt(String key, int defaultValue) {
                return (int) getValue(key, defaultValue, Integer.class);
            }

            @Mock
            public String getString(String key) {
                return getString(key, "");
            }

            @Mock
            public String getString(String key, String defaultValue) {
                return (String) getValue(key, defaultValue, String.class);
            }

            @Mock
            public void setSwitch(String key, Object value) {
                setSwitch(null, key, value);
            }

            @Mock
            public void setSwitch(String targetApp, String key, Object value) {
                qswitchMap.putIfAbsent(key, value);
            }

            @Mock
            private Object getValue(String key, Object defaultValue, Class<?> type) {
                final Object value = qswitchMap.get(key) != null ? qswitchMap.get(key) : defaultValue;
                if (!type.isInstance(value)) {
                    return defaultValue;
                }
                return value;
            }
        };
    }

}
